﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Runtime.InteropServices;

using System.Windows.Media.Imaging;

namespace MovieMaker
{
	public class ImageConverter
	{
		public ImageConverter()
		{
		}

		public System.Drawing.Image ByteArrayToImage(byte[] byteArrayIn)
		{
			var ms = new MemoryStream(byteArrayIn);
			var returnImage = System.Drawing.Image.FromStream(ms);
			return returnImage;
		}

		public Bitmap ToBitmap(byte[] byteArrayIn)
		{
			var ms = new MemoryStream(byteArrayIn);
			var returnImage = System.Drawing.Image.FromStream(ms);
			var bitmap = new System.Drawing.Bitmap(returnImage);

			return bitmap;
		}

		public BitmapSource ToBitmapSource(byte[] byteArrayIn)
		{
			var ms = new MemoryStream(byteArrayIn);
			var returnImage = System.Drawing.Image.FromStream(ms);
			var bitmap = new System.Drawing.Bitmap(returnImage);

			var bitSrc = ToBitmapSource(bitmap);

			bitmap.Dispose();
			bitmap = null;

			return bitSrc;
		}

		public BitmapSource ToBitmapSource(System.Drawing.Image source)
		{
			var bitmap = new System.Drawing.Bitmap(source);

			var bitSrc = ToBitmapSource(bitmap);

			bitmap.Dispose();
			bitmap = null;

			return bitSrc;
		}

		public BitmapSource ToBitmapSource(System.Drawing.Bitmap source)
		{
			BitmapSource bitSrc = null;

			var hBitmap = source.GetHbitmap();

			try
			{
				bitSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
					hBitmap,
					IntPtr.Zero,
					System.Windows.Int32Rect.Empty,
					BitmapSizeOptions.FromEmptyOptions());
			}
			catch (Win32Exception)
			{
				bitSrc = null;
			}
			finally
			{
				NativeMethods.DeleteObject(hBitmap);
			}

			return bitSrc;
		}

		public Bitmap ReduceBitmap(Bitmap original, int reducedWidth, int reducedHeight)
		{
			var reduced = new Bitmap(reducedWidth, reducedHeight);
			using (var dc = Graphics.FromImage(reduced))
			{
				// you might want to change properties like
				dc.InterpolationMode = InterpolationMode.HighQualityBicubic;
				dc.DrawImage(original, new Rectangle(0, 0, reducedWidth, reducedHeight), new Rectangle(0, 0, original.Width, original.Height), GraphicsUnit.Pixel);
			}

			return reduced;
		}

	}

	/// <summary>
	/// FxCop requires all Marshalled functions to be in a class called NativeMethods.
	/// </summary>
	internal static class NativeMethods
	{
		[DllImport("gdi32.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		internal static extern bool DeleteObject(IntPtr hObject);
	}
}
